/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.ec.payment.web.ApplyCashOutAction
   Module Description   :

   Date Created      : 2009/12/10
   Original Author   : feeling.wang
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.ec.payment.web;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.entity.SimplePager;
import com.yaodian100.core.common.service.DomainService;
import com.yaodian100.core.menu.entity.Menu;
import com.yaodian100.ec.common.EcConstant;
import com.yaodian100.ec.member.entity.Member;
import com.yaodian100.ec.member.service.MemberService;
import com.yaodian100.ec.payment.entity.ApplyCashOut;
import com.yaodian100.ec.payment.service.TransferService;

/**
 * @author feeling.wang
 * 
 */
public class ApplyCashOutAction extends ActionSupport implements Preparable {
	private static final long serialVersionUID = 6121945840783397185L;

	/** logger */
	private final Logger logger = LoggerFactory.getLogger(ApplyCashOutAction.class);

	private Menu cashOutTypeMenu; // 與 getter, setter
	private Menu cashOutStatusMenu; // 與 getter, setter
	private SimplePager pager;
	private DomainService<Menu> menuService; // 與 setter
	private TransferService transferService;
	@Autowired
	private MemberService memberService;
	private List<ApplyCashOut> applyCashOuts;
	private ApplyCashOut applyCashOut;

	private String cashOutTypeParam;
	private String cashOutStatusParam;
	private String startDateParam;
	private String endDateParam;
	private String applyCashOutId;
	private final static String NOT_ENOUGH_VIRTUAL_BALANCE = ":很抱歉，你目前的账户余额不足。";
	private final static String APPLY_CASH_OUT_FAILURE = ":提现失败";
	private final static String MEMBER_DATA_ERROR = ":会员资料错误";
	private final static String MEMBER_NOT_ACTIVED = ":未激活";

	/** 提现申请参数 **/
	private Member member;
	private String memberId;
	private String receiverName;
	private String receiverProvince;
	private String receiverCity;
	private String receiverDistrict;
	private String receiverAddress;
	private String receiverZipCode;
	private String receiverBankName;
	private String receiverBankName1;
	private String receiverBankName2;
	private String receiverBankAccountName;
	private String receiverBankAccountNumber;
	private String bankName;
	private String applyAmount;
	private BigDecimal fee;
	private String virtualBalance;
	private String actualCashOutAmount;
	private BigDecimal tempApplyAmount = new BigDecimal(0.00);
	private BigDecimal availableAmount;
	private String cashOutType = "1";

	public String edit() {
		initParam();
		memberId = null;
		cashOutType = "1";
		return "edit";
	}

	/**
	 * 初始化參數
	 */
	void initParam() {
		member = null;
		receiverName = null;
		receiverProvince = null;
		receiverCity = null;
		receiverDistrict = null;
		receiverAddress = null;
		receiverZipCode = null;
		receiverBankName = null;
		receiverBankName1 = null;
		receiverBankName2 = null;
		receiverBankAccountName = null;
		receiverBankAccountNumber = null;
		bankName = null;
		applyAmount = null;
		fee = BigDecimal.ZERO;
		virtualBalance = null;
		actualCashOutAmount = null;
		availableAmount = BigDecimal.ZERO;

	}

	/**
	 * 储存提现申请
	 * 
	 * @return
	 * @throws Exception
	 */
	public String save() {
		try {
			if (StringUtils.isNotBlank(memberId)) {
				member = memberService.get(memberId);
				if (null != member) {
					if (!"nonmember".equalsIgnoreCase(member.getApplySource()) && null == member.getActiveDate()) {
						addActionMessage(member.getLoginId() + MEMBER_NOT_ACTIVED);
					} else {
						if (!(cashOutValidate() && hasVirtualBalance(memberId) && !isTodayApplyCashOut())) {
							addActionMessage(member.getLoginId() + APPLY_CASH_OUT_FAILURE);
						} else {
							tempApplyAmount = new BigDecimal(applyAmount);
							if (member.getBalance().getVirtualBalance().compareTo(tempApplyAmount) >= 0) {
								applyCashOut = new ApplyCashOut();
								if (cashOutType.equals("1")) {
									applyCashOut.setReceiverName(receiverName);
									applyCashOut.setReceiverCity(receiverCity);
									applyCashOut.setReceiverProvince(receiverProvince);
									applyCashOut.setReceiverDistrict(receiverDistrict);
									applyCashOut.setReceiverAddress(receiverAddress);
									applyCashOut.setReceiverZipCode(receiverZipCode);
								} else {
									applyCashOut.setReceiverBankAccountName(receiverBankAccountName);
									applyCashOut.setReceiverBankName(StringUtils.defaultString(receiverBankName1, "")
											+ StringUtils.defaultString(receiverBankName2, ""));
									applyCashOut.setReceiverBankAccountNumber(receiverBankAccountNumber);
								}
								applyCashOut.setApplyAmount(tempApplyAmount);
								applyCashOut.setFee(new BigDecimal("0"));
								applyCashOut.setActualCashOutAmount(applyCashOut.getApplyAmount().subtract(applyCashOut.getFee()));
								applyCashOut.setCashOutType(cashOutType);
								applyCashOut.setMemberId(memberId);
								applyCashOut.setMemberName(member.getLoginId());
								applyCashOut.setCashOutStatus("10");// 处理中
								applyCashOut = transferService.saveApplyCashOut(applyCashOut);
								member = memberService.get(applyCashOut.getMemberId());
								return "success";
							} else {
								addActionMessage(member.getLoginId() + NOT_ENOUGH_VIRTUAL_BALANCE);
							}
						}
					}
				} else {
					addActionMessage(MEMBER_DATA_ERROR);
				}
			} else {
				addActionMessage(MEMBER_DATA_ERROR);
			}
		} catch (Exception e) {
			addActionMessage(member.getLoginId() + APPLY_CASH_OUT_FAILURE);
		}
		memberId = null;
		initParam();
		return "edit";
	}

	public String getMemberData() {
		initParam();
		if (StringUtils.isNotBlank(memberId)) {
			member = memberService.get(memberId);
			if (null == member) {
				addActionMessage(MEMBER_DATA_ERROR);
			} else {
				if (!"nonmember".equalsIgnoreCase(member.getApplySource()) && null == member.getActiveDate()) {
					addActionMessage(member.getLoginId() + MEMBER_NOT_ACTIVED);
				} else {
					if (member.getBalance().getVirtualBalance().compareTo(BigDecimal.ZERO) == 0) {
						addActionMessage(member.getLoginId() + NOT_ENOUGH_VIRTUAL_BALANCE);
					}
				}
			}
		}
		return "edit";
	}

	/**
	 * 验证提现资料
	 * 
	 * @return
	 * @throws Exception
	 */
	boolean cashOutValidate() throws Exception {
		if (cashOutType.equals("1")) {
			if (StringUtils.isBlank(receiverName) || StringUtils.length(receiverName) < 2
					|| StringUtils.length(receiverName) > 10) {
				addFieldError("receiverName", "收款人姓名不可為空值且長度須介於2~10個字元之間");
			}

			if (StringUtils.isBlank(receiverProvince)) {
				addFieldError("receiverProvince", "请选择省份/直辖市");
			}

			if (StringUtils.isBlank(receiverCity)) {
				addFieldError("receiverCity", "请选择市");
			}

			if (StringUtils.isBlank(receiverDistrict)) {
				addFieldError("receiverDistrict", "请选择县/区");
			}

			if (StringUtils.isBlank(receiverAddress)) {
				addFieldError("receiverAddress", "详细地址不可为空值");
			}

			if (StringUtils.isBlank(receiverZipCode)) {
				addFieldError("receiverZipCode", "邮递区码不可为空值");
			}
		} else {// 银行转帐
			if (StringUtils.isBlank(receiverBankAccountName) || StringUtils.length(receiverBankAccountName) < 2
					|| StringUtils.length(receiverBankAccountName) > 10) {
				addFieldError("receiverName", "开户人姓名不可為空值且長度須介於2~10個字元之間");
			}
			if (StringUtils.isBlank(receiverBankName1)) {
				addFieldError("receiverBankName1", "银行名称不可为空值");
			}
			if (StringUtils.isBlank(receiverBankName2)) {
				addFieldError("receiverBankName2", "分行名称不可为空值");
			}
			if (StringUtils.isBlank(receiverBankAccountNumber)) {
				addFieldError("receiverBankAccountNumber", "银行帐号不可为空值");
			}
		}
		if (StringUtils.isBlank(applyAmount) || !NumberUtils.isNumber(applyAmount)) {
			addFieldError("applyAmount", "提现金额不可为空值");
		}
		if (getFieldErrors().isEmpty()) {
			return true;
		} else {
			return false;
		}
	}

	BigDecimal calculateFee(BigDecimal calcApplyAmount) {
		BigDecimal tempApplyAmount = calcApplyAmount;
		BigDecimal tempFee = new BigDecimal(0.00);
		if (new BigDecimal(200).compareTo(tempApplyAmount) == 1 || new BigDecimal(200).compareTo(tempApplyAmount) == 0) {
			tempFee = new BigDecimal(2);
		} else if (new BigDecimal(200).compareTo(tempApplyAmount) == -1
				&& new BigDecimal(5000).compareTo(tempApplyAmount) == 1) {
			tempFee = new BigDecimal(applyAmount).multiply(new BigDecimal(0.01));
		} else if (new BigDecimal(5000).compareTo(tempApplyAmount) == -1) {
			tempFee = new BigDecimal(50);
		}
		return tempFee;
	}

	/**
	 * 验证帐户内的馀额是否大于0
	 * 
	 * @param memberId
	 * @return
	 * @throws Exception
	 */
	boolean hasVirtualBalance(String memberId) throws Exception {
		member = memberService.get(memberId);
		if (null != member) {
			if (member.getBalance().getVirtualBalance().compareTo(new BigDecimal(0)) == 1) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 验证今天是否已提现
	 * 
	 * @param memberId
	 * @return
	 * @throws Exception
	 */
	boolean isTodayApplyCashOut() throws Exception {
		return false;
	}

	public void prepare() throws Exception {
		clearErrorsAndMessages();

		if (null == pager) {
			pager = new SimplePager();
		}

		if (null == cashOutTypeMenu) {
			cashOutTypeMenu = menuService.get("ApplyCashOut.CashOutType");
		}

		if (null == cashOutStatusMenu) {
			cashOutStatusMenu = menuService.get("ApplyCashOut.CashOutStatus");
		}

		logger.info("prepare ok");
	}

	/**
	 * 查询提现资料
	 * 
	 * @return
	 * @throws Exception
	 */
	public String search() throws Exception {
		try {
			if (StringUtils.isBlank(startDateParam)) {
				startDateParam = EcConstant.PATTERN_DATE_FORMAT.format(DateUtils.addDays(new Date(), -30));
			}

			if (StringUtils.isBlank(endDateParam)) {
				endDateParam = EcConstant.PATTERN_DATE_FORMAT.format(new Date());
			}

			CommonCriteria crit = new CommonCriteria();
			if (StringUtils.isNotBlank(cashOutStatusParam)) {
				crit.addEq("cashOutStatus", cashOutStatusParam);
			}

			if (StringUtils.isNotBlank(cashOutTypeParam)) {
				crit.addEq("cashOutType", cashOutTypeParam);
			}

			String[] sortOrder = { "id" };
			crit.addGe("applyDate", DateUtils.parseDate(startDateParam, new String[] { EcConstant.PATTERN_DATE }));
			crit.addLe("applyDate", DateUtils.parseDate(endDateParam + " 23:59:59",
					new String[] { EcConstant.PATTERN_TIMESTAMP }));

			int applyCashOutSize = transferService.getApplyCashOutListSize(crit).intValue();
			pager.setTotalSize(applyCashOutSize);

			applyCashOuts = transferService.getApplyCashOutList(pager.getCurrentPage() * pager.getPageRecord(), pager
					.getPageRecord(), crit, sortOrder);
		} catch (Exception e) {
			addActionError(e.getMessage());
		}
		return "list";
	}

	/**
	 * 
	 * @return
	 */
	public String view() {
		if (StringUtils.isNotBlank(applyCashOutId)) {
			applyCashOut = transferService.getApplyCashOut(applyCashOutId);
		}
		return "view";
	}

	public void setApplyCashOut(ApplyCashOut applyCashOut) {
		this.applyCashOut = applyCashOut;
	}

	public void setApplyCashOuts(List<ApplyCashOut> applyCashOuts) {
		this.applyCashOuts = applyCashOuts;
	}

	public void setCashOutStatusMenu(Menu cashOutStatusMenu) {
		this.cashOutStatusMenu = cashOutStatusMenu;
	}

	public void setCashOutStatusParam(String cashOutStatusParam) {
		this.cashOutStatusParam = cashOutStatusParam;
	}

	public void setCashOutTypeMenu(Menu cashOutTypeMenu) {
		this.cashOutTypeMenu = cashOutTypeMenu;
	}

	public void setCashOutTypeParam(String cashOutTypeParam) {
		this.cashOutTypeParam = cashOutTypeParam;
	}

	public void setEndDateParam(String endDateParam) {
		this.endDateParam = endDateParam;
	}

	public void setMenuService(DomainService<Menu> menuService) {
		this.menuService = menuService;
	}

	public void setPager(SimplePager pager) {
		this.pager = pager;
	}

	public void setStartDateParam(String startDateParam) {
		this.startDateParam = startDateParam;
	}

	public void setTransferService(TransferService transferService) {
		this.transferService = transferService;
	}

	public String getApplyCashOutId() {
		return applyCashOutId;
	}

	public void setApplyCashOutId(String applyCashOutId) {
		this.applyCashOutId = applyCashOutId;
	}

	public ApplyCashOut getApplyCashOut() {
		return applyCashOut;
	}

	public List<ApplyCashOut> getApplyCashOuts() {
		return applyCashOuts;
	}

	public Menu getCashOutStatusMenu() {
		return cashOutStatusMenu;
	}

	public String getCashOutStatusParam() {
		return cashOutStatusParam;
	}

	public Menu getCashOutTypeMenu() {
		return cashOutTypeMenu;
	}

	public String getCashOutTypeParam() {
		return cashOutTypeParam;
	}

	public String getEndDateParam() {
		return endDateParam;
	}

	public SimplePager getPager() {
		return pager;
	}

	public String getStartDateParam() {
		return startDateParam;
	}

	public Member getMember() {
		return member;
	}

	public void setMember(Member member) {
		this.member = member;
	}

	public String getMemberId() {
		return memberId;
	}

	public void setMemberId(String memberId) {
		this.memberId = memberId;
	}

	public String getReceiverName() {
		return receiverName;
	}

	public String getReceiverProvince() {
		return receiverProvince;
	}

	public String getReceiverCity() {
		return receiverCity;
	}

	public String getReceiverDistrict() {
		return receiverDistrict;
	}

	public String getReceiverAddress() {
		return receiverAddress;
	}

	public String getReceiverZipCode() {
		return receiverZipCode;
	}

	public String getReceiverBankName() {
		return receiverBankName;
	}

	public String getReceiverBankName1() {
		return receiverBankName1;
	}

	public String getReceiverBankName2() {
		return receiverBankName2;
	}

	public String getReceiverBankAccountName() {
		return receiverBankAccountName;
	}

	public String getReceiverBankAccountNumber() {
		return receiverBankAccountNumber;
	}

	public String getBankName() {
		return bankName;
	}

	public String getApplyAmount() {
		return applyAmount;
	}

	public BigDecimal getFee() {
		return fee;
	}

	public String getVirtualBalance() {
		return virtualBalance;
	}

	public String getActualCashOutAmount() {
		return actualCashOutAmount;
	}

	public BigDecimal getTempApplyAmount() {
		return tempApplyAmount;
	}

	public BigDecimal getAvailableAmount() {
		return availableAmount;
	}

	public String getCashOutType() {
		return cashOutType;
	}

	public void setReceiverName(String receiverName) {
		this.receiverName = receiverName;
	}

	public void setReceiverProvince(String receiverProvince) {
		this.receiverProvince = receiverProvince;
	}

	public void setReceiverCity(String receiverCity) {
		this.receiverCity = receiverCity;
	}

	public void setReceiverDistrict(String receiverDistrict) {
		this.receiverDistrict = receiverDistrict;
	}

	public void setReceiverAddress(String receiverAddress) {
		this.receiverAddress = receiverAddress;
	}

	public void setReceiverZipCode(String receiverZipCode) {
		this.receiverZipCode = receiverZipCode;
	}

	public void setReceiverBankName(String receiverBankName) {
		this.receiverBankName = receiverBankName;
	}

	public void setReceiverBankName1(String receiverBankName1) {
		this.receiverBankName1 = receiverBankName1;
	}

	public void setReceiverBankName2(String receiverBankName2) {
		this.receiverBankName2 = receiverBankName2;
	}

	public void setReceiverBankAccountName(String receiverBankAccountName) {
		this.receiverBankAccountName = receiverBankAccountName;
	}

	public void setReceiverBankAccountNumber(String receiverBankAccountNumber) {
		this.receiverBankAccountNumber = receiverBankAccountNumber;
	}

	public void setBankName(String bankName) {
		this.bankName = bankName;
	}

	public void setApplyAmount(String applyAmount) {
		this.applyAmount = applyAmount;
	}

	public void setFee(BigDecimal fee) {
		this.fee = fee;
	}

	public void setVirtualBalance(String virtualBalance) {
		this.virtualBalance = virtualBalance;
	}

	public void setActualCashOutAmount(String actualCashOutAmount) {
		this.actualCashOutAmount = actualCashOutAmount;
	}

	public void setTempApplyAmount(BigDecimal tempApplyAmount) {
		this.tempApplyAmount = tempApplyAmount;
	}

	public void setAvailableAmount(BigDecimal availableAmount) {
		this.availableAmount = availableAmount;
	}

	public void setCashOutType(String cashOutType) {
		this.cashOutType = cashOutType;
	}

}